package com.log4jviewer.logfile;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.text.ParseException;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.log4jviewer.domain.LogEvent;
import com.log4jviewer.domain.LogList;
import com.log4jviewer.filters.LogFilterEngine;

public class LogFileLoaderTest {

    private LogFileLoader logFileLoader;

    private LogList logList;

    @Before
    public void init() {
        logList = new LogList(new LogFilterEngine(), 5);
        logFileLoader = new LogFileLoader();
        logFileLoader.addListener(logList);
    }

    @After
    public void dispose() {
        logFileLoader.removeListener(logList);
    }

    @Test
    public void createLogRecordsTest1() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile1.log";
        String logFilePattern = "%-5p [%t]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getLevel()).thenReturn("INFO").thenReturn("DEBUG");
        when(logMock.getThreadName()).thenReturn("main");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 7,1");

        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getThreadName(), logList.getFilteredLog(0).getThreadName());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getThreadName(), logList.getFilteredLog(1).getThreadName());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest2() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile2.log";
        String logFilePattern = "%r [%t] %-5p %c %x - %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getThreadName()).thenReturn("main");
        when(logMock.getLevel()).thenReturn("INFO");
        when(logMock.getCategoryName()).thenReturn("com.rusya7.swt.SwtCellClickProcessor").thenReturn(
                "com.rusya7.swt.DataViewer");
        when(logMock.getNdc()).thenReturn("");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 4,2");

        Assert.assertEquals(logMock.getThreadName(), logList.getFilteredLog(0).getThreadName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(0).getCategoryName());
        Assert.assertEquals(logMock.getNdc(), logList.getFilteredLog(0).getNdc());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getThreadName(), logList.getFilteredLog(1).getThreadName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(1).getCategoryName());
        Assert.assertEquals(logMock.getNdc(), logList.getFilteredLog(1).getNdc());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest3() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile3.log";
        String logFilePattern = "%-6r [%15.15t] %-5p %30.30c %x - %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getThreadName()).thenReturn("main");
        when(logMock.getLevel()).thenReturn("INFO");
        when(logMock.getCategoryName()).thenReturn("sya7.swt.SwtCellClickProcessor").thenReturn(
                "com.rusya7.swt.DataViewer");
        when(logMock.getNdc()).thenReturn("");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 3,2");

        Assert.assertEquals(logMock.getThreadName(), logList.getFilteredLog(0).getThreadName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(0).getCategoryName());
        Assert.assertEquals(logMock.getNdc(), logList.getFilteredLog(0).getNdc());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getThreadName(), logList.getFilteredLog(1).getThreadName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(1).getCategoryName());
        Assert.assertEquals(logMock.getNdc(), logList.getFilteredLog(1).getNdc());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest4() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile4.log";
        String logFilePattern = "[%d{dd MMM yyyy HH:mm:ss:SSS}][%L][%c{1}][%p]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getDate()).thenReturn("13 Dec 2011 14:30:31:421").thenReturn("13 Dec 2011 14:30:34:927");
        when(logMock.getLineNumber()).thenReturn("16").thenReturn("138");
        when(logMock.getCategoryName()).thenReturn("SwtCellClickProcessor").thenReturn("DataViewer");
        when(logMock.getLevel()).thenReturn("WARN").thenReturn("ERROR");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 9,2");

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(0).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(0).getLineNumber());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(0).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(1).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(1).getLineNumber());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(1).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest5() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile5.log";
        String logFilePattern = "%d{HH:mm:ss,SSS} - [%L][%c{1}][%p]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getDate()).thenReturn("14:31:03,443").thenReturn("14:31:21,547");
        when(logMock.getLineNumber()).thenReturn("16").thenReturn("138");
        when(logMock.getCategoryName()).thenReturn("SwtCellClickProcessor").thenReturn("DataViewer");
        when(logMock.getLevel()).thenReturn("INFO").thenReturn("FATAL");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 1,2");

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(0).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(0).getLineNumber());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(0).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(1).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(1).getLineNumber());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(1).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest6() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile6.log";
        String logFilePattern = "[%L][%C{1}][%p]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getLineNumber()).thenReturn("16").thenReturn("138");
        when(logMock.getClassName()).thenReturn("SwtCellClickProcessor").thenReturn("DataViewer$4");
        when(logMock.getLevel()).thenReturn("INFO");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 8,2");

        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(0).getLineNumber());
        Assert.assertEquals(logMock.getClassName(), logList.getFilteredLog(0).getClassName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(1).getLineNumber());
        Assert.assertEquals(logMock.getClassName(), logList.getFilteredLog(1).getClassName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest7() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile7.log";
        String logFilePattern = "%d{ISO8601} - [%L][%C{2}][%p]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getDate()).thenReturn("2011-12-13 14:32:27,550").thenReturn("2011-12-13 14:32:32,411");
        when(logMock.getLineNumber()).thenReturn("16").thenReturn("138");
        when(logMock.getClassName()).thenReturn("swt.SwtCellClickProcessor").thenReturn("swt.DataViewer$4");
        when(logMock.getLevel()).thenReturn("INFO");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 0,2");

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(0).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(0).getLineNumber());
        Assert.assertEquals(logMock.getClassName(), logList.getFilteredLog(0).getClassName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(1).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(1).getLineNumber());
        Assert.assertEquals(logMock.getClassName(), logList.getFilteredLog(1).getClassName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest8() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile8.log";
        String logFilePattern = "%d{ABSOLUTE} - [%L][%c{3}][%p]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getDate()).thenReturn("14:33:03,727").thenReturn("14:33:06,662");
        when(logMock.getLineNumber()).thenReturn("16").thenReturn("138");
        when(logMock.getCategoryName()).thenReturn("rusya7.swt.SwtCellClickProcessor").thenReturn(
                "rusya7.swt.DataViewer");
        when(logMock.getLevel()).thenReturn("INFO");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 7,2");

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(0).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(0).getLineNumber());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(0).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(1).getDate());
        Assert.assertEquals(logMock.getLineNumber(), logList.getFilteredLog(1).getLineNumber());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(1).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest9() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile9.log";
        String logFilePattern = "[%F][%M][%p]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getFileName()).thenReturn("SwtCellClickProcessor.java").thenReturn("DataViewer.java");
        when(logMock.getMethodName()).thenReturn("main").thenReturn("isEditorActivationEvent");
        when(logMock.getLevel()).thenReturn("INFO");
        when(logMock.getMessage()).thenReturn("Log4j configuration was successfully loaded.").thenReturn(
                "Selected item/cell: 6,2");

        Assert.assertEquals(logMock.getFileName(), logList.getFilteredLog(0).getFileName());
        Assert.assertEquals(logMock.getMethodName(), logList.getFilteredLog(0).getMethodName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getFileName(), logList.getFilteredLog(1).getFileName());
        Assert.assertEquals(logMock.getMethodName(), logList.getFilteredLog(1).getMethodName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());
    }

    @Test
    public void createLogRecordsTest10() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile10.log";
        String logFilePattern = "%d{DATE} [%p]%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(2, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getDate()).thenReturn("13 Dec 2011 14:35:14,873").thenReturn("13 Dec 2011 14:35:19,811");
        when(logMock.getLevel()).thenReturn("INFO");

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(0).getDate());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(1).getDate());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
    }

    @Test
    public void createLogRecordsTest11() throws IOException, ParseException {
        String logFilePath = "testinputs/log4jviewer/logfile/testLogFile11.log";
        String logFilePattern = "[%d{HH:mm:ss:SSS}][%c{1}][%p]: %m%n";
        logFileLoader.load(logFilePath, logFilePattern);

        Assert.assertEquals(4, logList.getFilteredLogsNum());

        LogEvent logMock = mock(LogEvent.class);
        when(logMock.getDate()).thenReturn("13:53:28:632");
        when(logMock.getCategoryName()).thenReturn("AbstractBatcher").thenReturn("SQL").thenReturn("AbstractBatcher")
                .thenReturn("StringType");
        when(logMock.getLevel()).thenReturn("DEBUG");
        when(logMock.getMessage())
                .thenReturn("about to open PreparedStatement (open PreparedStatements: 0, globally: 0)")
                .thenReturn("select\n        * \n    from\n        ( select\n            this_.id as y0_ "
                        + "\n        from\n            DET2.company_period this_ \n        where\n            "
                        + "this_.co_id=? \n        order by\n            this_.period_end desc,\n            "
                        + "this_.period_length desc ) \n    where\n        rownum <= ?")
                .thenReturn("preparing statement")
                .thenReturn("binding '5758' to parameter: 1");

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(0).getDate());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(0).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(0).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(0).getMessage());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(1).getDate());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(1).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(1).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(1).getMessage());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(2).getDate());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(2).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(2).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(2).getMessage());

        Assert.assertEquals(logMock.getDate(), logList.getFilteredLog(3).getDate());
        Assert.assertEquals(logMock.getCategoryName(), logList.getFilteredLog(3).getCategoryName());
        Assert.assertEquals(logMock.getLevel(), logList.getFilteredLog(3).getLevel());
        Assert.assertEquals(logMock.getMessage(), logList.getFilteredLog(3).getMessage());
    }
}
